'''
Created on Dec 16, 2013

@author: dan
'''

import sys
from nltk.corpus import wordnet
from nltk.stem.wordnet import WordNetLemmatizer

Pronouns = { 'another'  : 'thing',
             'it'       : 'thing',
             'her'      : 'person',
             'him'      : 'person',
             'them'     : 'group'}

def full_hyponymy(synset):
    result = [synset]
    for hyponym in synset.hyponyms():
        result = result + full_hyponymy(hyponym)
    return result

def full_hypernymy(synset):
    result = [synset]
    for hypernym in synset.hypernyms():
        result = result + full_hypernymy(hypernym)
    return result

'''the meronymsenses functions that are passed to meronymsenses(3)'''
def part( word ):
    return word.part_holonyms()
def member( word ):
    return word.member_holonyms()
def substance( word ):
    return word.substance_holonyms()


'''Tests Wordnet's hypernymy and meronymsenses graphs to determine whether
   word2 is a part of word1. Since meronymsenses takes three forms in
   wordnet, a function is also passed. meronymytype is a function
   that determines the meronymsenses paths to follow'''
def meronymsenses( word1, word2, meronymytype ):
    
    lmtzr = WordNetLemmatizer()
    if lmtzr.lemmatize( word1, 'n') == lmtzr.lemmatize( word2, 'n'): 
        return None 
    if word1 in Pronouns or word2 in Pronouns:
        return None
    word1senses = wordnet.synsets(word1, pos=wordnet.NOUN)
    word2senses = wordnet.synsets(word2, pos=wordnet.NOUN)
    if not word1senses or not word2senses:
        return None
    
    '''full hypernymy/hyponymy inheritance tree for the first word'''
    A = set(word1senses)
    for sense in word1senses:
        for hypernym in full_hypernymy(sense):
            A.add(hypernym)
        for hyponym in full_hyponymy(sense):
            A.add(hyponym)

    B = set(word2senses)
    for sense in word2senses:
        for hyponym in full_hyponymy(sense):
            B.add(hyponym)
    
    #print A
    for word in B:
        result = findMero( 0, A, word, meronymytype )
        if result != None:
            return result
            break
    
def findMero( count, goals, synset, merotype):
    if synset in goals:
        return str(synset)
    elif count > N:
        return None
    else:
        C = set()
        for word in full_hyponymy(synset):
            C = C.union( merotype(word) )
        for word in C:
            result = findMero( count + 1, goals, word, merotype )
            if result != None:
                return str(synset) + result
        return None

N = 5

if __name__ == '__main__':
    if len(sys.argv) != 3:
        print 'Usage: python ' + sys.argv[0] + ' holonym meronym'
    elif sys.argv[1] == '-f':
        infile = open( sys.argv[2], 'r')
        right = 0
        wrong = 0
        noguess = 0
        
        for line in infile:
            line = line.split(' ')
            noun1 = line[2]
            noun2 = line[4]
            answer = line[5].rstrip()
            
            if( meronymsenses( noun1, noun2, member ) or \
                meronymsenses( noun1, noun2, part ) or \
                meronymsenses( noun1, noun2, substance )):
                print line
                if answer == 'N':
                    right = right + 1
                elif answer == 'V':
                    wrong = wrong + 1
            else:
                noguess = noguess + 1
        print right, wrong, noguess
    else:
        print meronymsenses( sys.argv[1], sys.argv[2], member )
        print meronymsenses( sys.argv[1], sys.argv[2], part )
        print meronymsenses( sys.argv[1], sys.argv[2], substance ) 